using System;
using System.Data;
using PCSComUtils.PCSExc;
using PCSComUtils.Common;
using PCSComProduct.Items.DS;
using PCSComUtils.DataContext;
using PCSComUtils.DataAccess;
using System.Linq;
namespace PCSComProduct.Items.BO
{
    public class ITM_CategoryBO //: ICategoryBO
    {
        private const string THIS = ".IITM_CategoryBO";
        public ITM_CategoryBO()
        {
        }

        ///    <Description>
        ///       This method checks business rule and call Add() method of DS class 
        ///    </Description>
        ///    <Inputs>
        ///       Value object    
        ///    </Inputs>
        ///    <Outputs>
        ///      N/A   
        ///    </Outputs>
        ///    <Returns>
        ///      void
        ///    </Returns>
        ///    <Authors>
        ///       HungLa
        ///    </Authors>
        ///    <History>
        ///     13-Dec-2004
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        //[AutoComplete(true)]
        public bool Add(ITM_Category pobjObjectVO)
        {
            bool ret = true;
            using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
            {
                try
                {
                    db.ITM_Categories.InsertOnSubmit(pobjObjectVO);
                    db.SubmitChanges();
                }
                catch (Exception ex)
                {
                    ret = false;
                }
            }
            return ret;
        }

        //**************************************************************************              
        ///    <Description>
        ///       This method checks business rule and call Delete() method of DS class 
        ///    </Description>
        ///    <Inputs>
        ///        pintID      
        ///    </Inputs>
        ///    <Outputs>
        ///     Delete a record  from Database
        ///    </Outputs>
        ///    <Returns>
        ///       void
        ///    </Returns>
        ///    <Authors>
        ///       HungLa
        ///    </Authors>
        ///    <History>
        ///    13-Dec-2004 
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        //[AutoComplete(true)]
        public bool Delete(int pintID)
        {
            bool ret = true;
            using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
            {
                try
                {
                    db.ITM_Categories.DeleteOnSubmit(db.ITM_Categories.Single(e => e.CategoryID == pintID));
                    db.SubmitChanges();
                }
                catch { ret = false; }
            }
            return ret;
        }

        public ITM_Category GetCategoryByCode(string strCategoryCode)
        {
            using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
            {
                return db.ITM_Categories.Single(e => e.Code == strCategoryCode);
            }
        }
        public ITM_Category GetCategoryByProductCode(string strProductCode)
        {
            using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
            {
                var obj = (from objCategory in db.ITM_Categories
                           join objProduct in db.ITM_Products
                            on objCategory.CategoryID equals objProduct.CategoryID
                           where objProduct.Code == strProductCode
                           select objCategory).Single<ITM_Category>();
                return obj;
            }
        }
        public ITM_Category GetCategoryByProductID(int iProductID)
        {
            using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
            {
                var obj = (from objCategory in db.ITM_Categories
                           join objProduct in db.ITM_Products
                            on objCategory.CategoryID equals objProduct.CategoryID
                           where objProduct.ProductID == iProductID
                           select objCategory).Single<ITM_Category>();
                return obj;
            }
        }
        public ITM_Category GetCategory(int iId)
        {
            using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
            {
                return db.ITM_Categories.Single(e => e.CategoryID == iId);
            }
        }
        //**************************************************************************              
        ///    <Description>
        ///       This method uses to update data
        ///    </Description>
        ///    <Inputs>
        ///       pobjObjecVO
        ///    </Inputs>
        ///    <Outputs>
        ///       
        ///    </Outputs>
        ///    <Returns>
        ///       void
        ///    </Returns>
        ///    <Authors>
        ///       HungLa 
        ///    </Authors>
        ///    <History>
        ///    13-Dec-2004   
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        //[AutoComplete(true)]
        public bool Update(ITM_Category pobjObjecVO)
        {
            bool ret = true;
            using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
            {
                try
                {
                    var obj = db.ITM_Categories.Single(e => e.CategoryID == pobjObjecVO.CategoryID);
                    obj.CatalogName = pobjObjecVO.CatalogName;
                    obj.Code = pobjObjecVO.Code;
                    obj.Description = pobjObjecVO.Description;
                    obj.Name = pobjObjecVO.Name;
                    obj.ParentCategoryId = pobjObjecVO.ParentCategoryId;
                    obj.Picture = pobjObjecVO.Picture;
                    db.SubmitChanges();
                }
                catch (Exception ex)
                {
                    ret = false;
                }
            }
            return ret;
        }

        //**************************************************************************              
        ///    <Description>
        ///      This method uses to get all data
        ///    </Description>
        ///    <Inputs>
        ///               
        ///    </Inputs>
        ///    <Outputs>
        ///    
        ///    </Outputs>
        ///    <Returns>
        ///       DataSet
        ///    </Returns>
        ///    <Authors>
        ///       HungLa 
        ///    </Authors>
        ///    <History>
        ///      
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        //[AutoComplete(true)]
        public DataSet List()
        {
            ITM_CategoryDS templateDS = new ITM_CategoryDS();
            return templateDS.List();
        }

        //**************************************************************************              
        ///    <Description>
        ///       This method uses to update a DataSet
        ///    </Description>
        ///    <Inputs>
        ///        DataSet       
        ///    </Inputs>
        ///    <Outputs>
        ///      N/A 
        ///    </Outputs>
        ///    <Returns>
        ///       void
        ///    </Returns>
        ///    <Authors>
        ///       HungLa
        ///    </Authors>
        ///    <History>
        ///       13-Dec-2004
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        //[AutoComplete(true)]
        public void UpdateDataSet(DataSet pData)
        {
            ITM_CategoryDS templateDS = new ITM_CategoryDS();
            templateDS.UpdateDataSet(pData);
        }

        //**************************************************************************              
        ///    <Description>
        ///       This method uses to check before add child for category
        ///    </Description>
        ///    <Inputs>
        ///        pintCategoryID       
        ///    </Inputs>
        ///    <Outputs>
        ///    </Outputs>
        ///    <Returns>
        ///       void
        ///    </Returns>
        ///    <Authors>
        ///       TuanDm
        ///    </Authors>
        ///    <History>
        ///       Monday, January 24, 2005
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        //[AutoComplete(true)]
        public bool CheckAddNewCategory(int pintCategoryID)
        {
            ITM_CategoryDS dsCategory = new ITM_CategoryDS();
            return dsCategory.CheckAddNewCategory(pintCategoryID);
        }

        //**************************************************************************              
        ///    <Description>
        ///       This method uses to check before add child for category
        ///    </Description>
        ///    <Inputs>
        ///        pintCategoryID       
        ///    </Inputs>
        ///    <Outputs>
        ///    </Outputs>
        ///    <Returns>
        ///       void
        ///    </Returns>
        ///    <Authors>
        ///       TuanDm
        ///    </Authors>
        ///    <History>
        ///       Monday, January 24, 2005
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        private bool CheckCategoryUsed(int pintCategoryID)
        {
            ITM_CategoryDS dsCategory = new ITM_CategoryDS();
            return dsCategory.CheckCategoryUsed(pintCategoryID);
        }

        //**************************************************************************              
        ///    <Description>
        ///       Check the category could be delete
        ///    </Description>
        ///    <Inputs>
        ///        int pintCategoryID, DataSet ds      
        ///    </Inputs>
        ///    <Outputs>
        ///    </Outputs>
        ///    <Returns>
        ///       true : if allow
        ///       false : if not allow
        ///    </Returns>
        ///    <Authors>
        ///       TuanDm
        ///    </Authors>
        ///    <History>
        ///       Thursday, January 20, 2005
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        private bool ValidateDeleteItem(int pintCategoryID, DataSet ds)
        {
            DataRow[] drChild = ds.Tables[ITM_CategoryTable.TABLE_NAME].Select("ParentCategoryID =" + pintCategoryID.ToString().Trim());
            if (drChild.Length == 0)
            {
                if (CheckCategoryUsed(pintCategoryID))
                {
                    return false;
                }
            }
            else
            {
                foreach (DataRow dr in drChild)
                {
                    ValidateDeleteItem(int.Parse(dr[ITM_CategoryTable.CATEGORYID_FLD].ToString()), ds);
                }
            }
            return true;
        }

        //**************************************************************************              
        ///    <Description>
        ///       Delete recusive a category
        ///    </Description>
        ///    <Inputs>
        ///       int pintCategoryID, DataSet ds : contains all categories       
        ///    </Inputs>
        ///    <Outputs>
        ///    </Outputs>
        ///    <Returns>
        ///       void
        ///    </Returns>
        ///    <Authors>
        ///       TuanDm
        ///    </Authors>
        ///    <History>
        ///       Monday, January 24, 2005
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        //[AutoComplete(true)]
        public void Delete(int pintCategoryID, DataSet ds)
        {
            DataRow[] drChild = ds.Tables[ITM_CategoryTable.TABLE_NAME].Select("ParentCategoryID =" + pintCategoryID.ToString().Trim());
            if (drChild.Length == 0)
            {
                Delete(pintCategoryID);
            }
            else
            {
                foreach (DataRow dr in drChild)
                {
                    Delete(int.Parse(dr[ITM_CategoryTable.CATEGORYID_FLD].ToString()), ds);
                }
            }
        }

        //**************************************************************************              
        ///    <Description>
        ///    Check and delete a category
        ///    </Description>
        ///    <Inputs>
        ///        pintCategory       
        ///    </Inputs>
        ///    <Outputs>
        ///    </Outputs>
        ///    <Returns>
        ///       void
        ///    </Returns>
        ///    <Authors>
        ///       TuanDm
        ///    </Authors>
        ///    <History>
        ///       Monday, January 24, 2005
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        //[AutoComplete(true)]
        public void CheckAndDelete(int pintCategory)
        {
            DataSet dsListCategory = List();
            if (ValidateDeleteItem(pintCategory, dsListCategory))
            {
                Delete(pintCategory, dsListCategory);            
            }
            else
            {
                throw new PCSBOException(ErrorCode.CASCADE_DELETE_PREVENT, "DeleteNode", new Exception());
            }
        }
    }
}
